const RestService = require('../../services/rest');
const { success, fail, paginate } = require('../../util/core');
const { autoTransaction } = require('../../util/db');
const { errorRes } = require('../../config');
class RestController {
    REST_SUCCESS = {
        ADD: "添加成功",
        DEL: "删除成功",
        RESTORE: "恢复成功",
        UPDATE: "更新成功",
        QUERY: "查询成功"
    }
    RESTE_ERROR = {
        ADD: "数据添加失败",
        DEL: "数据删除失败",
        RESTORE: "数据恢复失败",
        UPDATE: "数据更新失败",
        QUERY: "未获取到有效数据"
    }
    async addController(ctx) {
        await autoTransaction(async (session) => {
            (ctx.modelName !== 'User') && (ctx.request.body.user = ctx.user._id);
            const res = await RestService.addService(ctx, { data: ctx.request.body, session });
            if (!res) throw new Error(this.RESTE_ERROR.ADD);
            if (res.deletedCount) success(ctx, res, this.REST_SUCCESS.DEL)
            else success(ctx, res, this.REST_SUCCESS.ADD)
        }).catch(err => {
            fail(ctx, errorRes.addError.message, errorRes.addError.code, err.message)
        })
    }

    async delController(ctx, force = true) {
        await autoTransaction(async (session) => {
            const res = await RestService.delService(ctx, { data: ctx.request.body, force, session });
            if (force) {
                if (!res || res.deletedCount || res.modifiedCount) throw new Error(this.RESTE_ERROR.DEL)
            } else {
                if (!res || !res.modifiedCount) throw new Error(this.RESTE_ERROR.RESTORE)
            }
            success(ctx, res, this.REST_SUCCESS.DEL)
        }).catch(err => {
            fail(ctx, errorRes.deleteError.message, errorRes.deleteError.code, err.message)
        })
    }

    async softDelController(ctx) {
        await this.delController(ctx, false);
    }

    async restoreController(ctx) {
        await autoTransaction(async (session) => {
            const res = await RestService.restoreService(ctx, { data: ctx.request.body, session });
            success(ctx, res, this.REST_SUCCESS.RESTORE)
        }).catch(err => {
            fail(ctx, errorRes.restoreError.message, errorRes.restoreError.code, err.message)
        })
    }

    async updateController(ctx) {
        await autoTransaction(async (session) => {
            const res = await RestService.updateService(ctx, { data: ctx.request.body, session });
            if (!res || !res.modifiedCount) throw new Error(this.RESTE_ERROR.UPDATE);
            success(ctx, res, this.REST_SUCCESS.UPDATE)
        }).catch(err => {
            fail(ctx, errorRes.updateError.message, errorRes.updateError.code, err.message)
        })
    }

    async getByIdController(ctx) {
        await autoTransaction(async (session) => {
            const res = await RestService.getByIdService(ctx, { id: ctx.params.id, session });
            if (!res) throw new Error(this.RESTE_ERROR.QUERY);
            success(ctx, res, this.REST_SUCCESS.QUERY)
        }).catch(err => {
            fail(ctx, errorRes.queryError.message, errorRes.queryError.code, err.message)
        })
    }

    async getByPageController(ctx) {
        await autoTransaction(async (session) => {
            const setOpts = {}
            const { count, rows } = await RestService.getByPageService(ctx, {
                offset: (ctx.params.page * 1 - 1) * ctx.params.limit,
                limit: ctx.params.limit * 1,
                session
            });
            if (!rows) throw new Error(this.RESTE_ERROR.QUERY);
            paginate(ctx, rows, ctx.params.page, count, ctx.params.limit, this.REST_SUCCESS.QUERY)
        }).catch(err => {
            fail(ctx, errorRes.queryError.message, errorRes.queryError.code, err.message)
        })
    }

    async getAllController(ctx) {
        await autoTransaction(async (session) => {
            const setOpts = {};
            switch (ctx.modelName) {
                case 'Article':
                    setOpts.populate = ['shareCount', 'likeCount', 'commentCount', 'favoriteCount', 'viewCount']
                    break;
            }
            const res = await RestService.getAllService(ctx, { session, setOpts, query: ctx.query })
            if (!res) throw new Error(this.RESTE_ERROR.QUERY);
            success(ctx, res, this.REST_SUCCESS.QUERY)
        }).catch(err => {
            fail(ctx, errorRes.queryError.message, errorRes.queryError.code, err.message)
        })
    }
}
const restController = new RestController();
// const methodNames = Object.getOwnPropertyNames(RestController.prototype);
// const className = methodNames.shift();
// for(const methodName of methodNames){
//     const method = restController[methodName];
//     if(typeof method === 'function'){
//         const path = `${__filename}-->${restController[className]['name']}-${methodName}`;
//         method.__proto__.path = path
//     }
// }
module.exports = restController;